<?php

namespace services\member;

use api\modules\v1\forms\member\MemberForm;
use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\DateHelper;
use common\helpers\RedisHelper;
use common\helpers\ValidatorHelper;
use common\models\base\Department;
use common\models\base\Job;
use common\models\member\Attr;
use common\models\member\Member;
use common\models\rbac\Action;
use Exception;
use services\api\AccessTokenService;
use services\base\DepartmentService;
use services\base\JobService;
use services\base\ProjectService;
use services\buss\AccountsService;
use services\buss\DevicesService;
use services\buss\ScardService;
use services\log\LogMemberOpService;
use services\rbac\ActionService;
use services\rbac\MenuService;
use services\rbac\RolePermissionService;
use services\rbac\RoleService;
use services\rbac\MemberRoleService;
use Yii;

/**
 * Class MemberService
 * @package services\member
 *
 */
class MemberService extends Service
{
    /**
     * 用户列表
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getListPage(array $params = [], int $page = 0, int $pageSize = 0): array
    {
        $query = Member::find()->alias('m')
            ->where(['!=', 'm.super_type', Member::SUPER_TYPE_SUPER_ADMIN]);

        if (isset($params['keyword']) && $params['keyword']) {
            if (ValidatorHelper::validateMobile($params['keyword'])) {
                $query->andWhere(['m.mobile' => $params['keyword']]);
            } else {
                $query->andWhere(['like', 'm.realname', $params['keyword']]);
            }
        }

        if (isset($params['role_id']) && $params['role_id']) {
            $query->andWhere(['m.id' => MemberRoleService::getRoleUserIds($params['role_id'])]);
        }
        if (isset($params['status']) && is_numeric($params['status'])) {
            $query->andWhere(['m.status' => $params['status']]);
        } else {
            $query->andWhere(['m.status' => [Member::STATUS_INVALID, Member::STATUS_ENABLE]]);
        }
        if (isset($params['order_column']) && $params['order_column']) {
            $sort = isset($params['order_sort']) && $params['order_sort'] == 'asc' ? SORT_ASC : SORT_DESC;
            switch ($params['order_column']) {
                case 'last_time':
                    $order['m.last_time'] = $sort;
                    break;
                default :
                    break;
            }
        }
        $order['status'] = SORT_DESC;
        $order['id'] = SORT_DESC;

        return $this->getListPageRes($query, $page, $pageSize, $order);
    }

    /**
     * 格式化列表
     * @param array $data
     * @return array
     */
    public function getListPageFormat(array $data = []): array
    {
        $list = [];
        foreach ($data as $row) {
            $roleData = self::getMemberRoleIds($row['id']);
            $list[] = [
                'id' => $row['id'],
                'username' => $row['username'],
//                'realname' => $row['realname'],
                'mobile' => $row['mobile'],
                'role_name_arr' => $roleData ? array_column(RoleService::getNormalCacheListByIds($roleData['role_ids']), 'name') : '',
//                'status' => $row['status'],
                'status_str' => Member::$statuss[$row['status']] ?? '',
                'last_time_str' => DateHelper::timestampToDate($row['last_time'], DateHelper::DATE_FORMAT_4),
//                'created_at_str' => DateHelper::timestampToDate($row['created_at']),
            ];
        }
        return $list;
    }

    /**
     * 列表筛选项
     * @return array
     */
    public function getSelectCondition(): array
    {
        return [
            'role' => RoleService::getListCondition(),
            'status' => self::getStatusCondition(),
        ];
    }

    /**
     * 状态下拉筛选项
     * @return array[]
     */
    public static function getStatusCondition(): array
    {
        return [
            ['value' => Member::STATUS_ENABLE, 'label' => Member::$statuss[Member::STATUS_ENABLE]],
            ['value' => Member::STATUS_INVALID, 'label' => Member::$statuss[Member::STATUS_INVALID]],
        ];
    }

    /**
     * 根据Ids获取有效人员列表
     * @param array|int|null $orIds
     * @return Member[]
     */
    public static function getEnableListByIds(?array $ids = null, $orIds = null): array
    {
        $query = Member::find()
            ->where([
                'status' => Member::STATUS_ENABLE
            ])
            ->andWhere(['!=', 'super_type', Member::SUPER_TYPE_SUPER_ADMIN]);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        if ($orIds) {
            $query->orWhere(['id' => $orIds, 'status' => [Member::STATUS_INVALID, Member::STATUS_ENABLE]]);
        }
        return $query->orderBy(['id' => SORT_ASC])->all();
    }

    /**
     * 根据Ids获取人员列表【禁用 + 正常】
     * @param array|null $ids 指定人员IDs
     * @return Member[]
     */
    public static function getNormalListByIds(?array $ids = []): array
    {
        $query = Member::find()
            ->select(['*'])
            ->where([
                'status' => [Member::STATUS_INVALID, Member::STATUS_ENABLE],
            ]);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        return $query->orderBy(['id' => SORT_ASC])->all();
    }

    /**
     * 获取列表筛选项
     * @param array $ids
     * @return array
     */
    public static function getListCondition(array $ids = []): array
    {
        return CommonHelper::getListCondition(self::getNormalListByIds($ids), ['value_column' => 'id', 'label_column' => 'realname']);
    }

    /**
     * 获取编辑筛选项
     * @param array|int|null $ids
     * @param array|int|null $orIds
     * @return array
     */
    public static function getEditCondition($ids, $orIds = null): array
    {
        return CommonHelper::getListCondition(self::getEnableListByIds($ids, $orIds), ['value_column' => 'id', 'label_column' => 'realname']);
    }

    /**
     * 用户信息
     * @param int $id
     * @return array
     */
    public function getInfo(int $id): array
    {
        $data = [];
        $member = Member::findOne($id);
        if ($member) {
            // 用户角色
            $roleData = self::getMemberRoleIds($member->id);
            $data = [
                'id' => $member->id,
                'username' => $member->username,
                'mobile' => $member->mobile,
                'status' => $member->status,
                'role_id' => $roleData['role_ids'],
//                    'super_type' => $member->super_type,
            ];
        }

        $roleIds = [];
        $condition = [
            'role' => RoleService::getEditCondition($roleIds ?: null,$data['role_id'] ?? null),
        ];
        if ($data) {
            $data['role_id'] = array_intersect($data['role_id'], array_column($condition['role'], 'value'));
        }
        return array_merge($data, ['condition' => $condition]);
    }

    /**
     * 获取登陆用户权限
     * @return array
     */
    public function getMemberPerssions()
    {
        $member = Member::findOne(Yii::$app->user->identity->member_id);

        // 1.获取用户列表权限
        $rolePermissionService = new RolePermissionService();
        $auth = $rolePermissionService->getMemberPermissions($member);

        return [
            'auth' => $auth,// 权限
        ];
    }

    /**
     * 验证权限
     * @param Member $member 用户信息
     * @param string $route 路由
     * @return bool
     */
    public static function checkPermission(Member $member, string $route): bool
    {
        // 超管无需验证
        if ($member->super_type == Member::SUPER_TYPE_SUPER_ADMIN) {
            return true;
        }

        // 权限信息
        $action = Action::findOne([
            'flag' => $route,
            'status' => Action::STATUS_ENABLE,
        ]);
        if ($action) {
            // 用户角色
            $roleData = self::getMemberRoleIds($member->id);
            $actionList = RolePermissionService::getActionList($roleData['role_ids']);

            $actionIds = array_column($actionList, 'id');
            return in_array($action->id, $actionIds);
        }

        return true;
    }

    /**
     * 获取用户所有角色
     * @param int $id
     * @return array
     */
    public static function getMemberRoleIds(int $id): array
    {
        // 获取用户绑定角色
        $roleIds = MemberRoleService::getUserRoleEnableIds($id);

        return [
            'role_ids' => $roleIds,
        ];
    }

    /**
     * 获取当前用户权限【菜单 + 动作】
     * @param Member $member
     * @param int $roleId
     * @return array
     */
    public static function getMemberLimitData(Member $member, int $roleId = 0): array
    {
        $hasRoleIds = [];
        if ($member->super_type == Member::SUPER_TYPE_SUPER_ADMIN) {// 超管or项目管理员
            $menuList = MenuService::getEnableList();
            $actionList = ActionService::getEnableList();
        } else {
            // 获取用户绑定角色
            $roleData = self::getMemberRoleIds($member->id);
            $hasRoleIds = $roleData['role_ids'];
            $roleIds = $roleData['role_ids'];
            $roleId && $roleIds[] = $roleId;
            $menuList = RolePermissionService::getMenuList($roleIds);
            $actionList = RolePermissionService::getActionList($roleIds);
        }
        return [
            'role_ids' => $hasRoleIds,// 用户绑定角色IDs
            'menu' => $menuList,
            'action' => $actionList,
        ];
    }

    /**
     * 记录最近一次登陆时间、IP
     * @param Member $member
     * @return void
     * @throws Exception
     */
    public static function lastLogin(Member $member): void
    {
        // 1.记录访问次数
        $member->visit_count += 1;
        $member->last_time = time();
        $member->last_ip = Yii::$app->request->getUserIP();
        $member->saveAndCheckResult();
    }

    /**
     * 编辑项目
     * @param Member $member
     * @param MemberForm $model
     * @return Member
     * @throws \Exception
     */
    public static function editModel(Member $member, MemberForm $model): Member
    {
        $member->username = $model->username;
        $member->realname = $model->username;
        $member->mobile = $model->mobile;
        if ($model->password) {
            $member->password_hash = Yii::$app->security->generatePasswordHash($model->password);
            $member->auth_key = Yii::$app->security->generateRandomString();
        }
        $member->super_type = Member::SUPER_TYPE_NORMAL;
        /*if (Yii::$app->user->identity->member->super_type == Member::SUPER_TYPE_SUPER_ADMIN) {
            $member->super_type = $model->super_type;
        }*/
        $member->status = $model->status;
        $member->saveAndCheckResult();

        return $member;
    }

    /**
     * 新增用户
     * @param MemberForm $model
     * @return array
     */
    public function create(MemberForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.新增用户
            $member = new Member();
            $member = self::editModel($member, $model);

            // 3.添加角色绑定关系
            MemberRoleService::editModel($member, $model);
            // 4.日志
            LogMemberOpService::createMemberLog($model, $member, null);

            $transaction->commit();
            return ['id' => $member->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 编辑用户
     * @param MemberForm $model
     * @return array
     */
    public function update(MemberForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.编辑用户
            $oldMember = new Member();
            $oldMember->setAttributes($model->getMember()->getAttributes());
            $member = self::editModel($model->getMember(), $model);

            // 3.编辑角色绑定关系
            MemberRoleService::editModel($member, $model);
            // 4.日志
            LogMemberOpService::createMemberLog($model, $member, $oldMember);
            // 5.更新缓存
            RedisHelper::setMember($member);

            $transaction->commit();
            return ['id' => $member->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 删除用户
     * @param MemberForm $model
     * @return array
     */
    public function delete(MemberForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.删除用户
            $member = $model->getMember();
            $member->status = Member::STATUS_DELETE;
            $member->saveAndCheckResult();
            // 1-2.退出登陆
            AccessTokenService::clearMemeberToken($member->id);
            // 2.日志
            LogMemberOpService::createMemberLog($model, $member);
            // 3.更新缓存
            RedisHelper::setMember($member);

            $transaction->commit();
            return ['id' => $member->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 修改密码
     * @param MemberForm $model
     * @return array
     */
    public function updatePassword(MemberForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();
            // 1.修改密码
            $member = $model->getMember();
            $member->password_hash = Yii::$app->security->generatePasswordHash($model->new_password);
            $member->auth_key = Yii::$app->security->generateRandomString();
            $member->saveAndCheckResult();

            // 2.日志
            LogMemberOpService::createMemberLog($model, $member);

            $transaction->commit();
            return ['id' => $member->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }
}
